<script setup>
import { computed, ref, onBeforeUnmount, onMounted, nextTick } from 'vue';
import { useRoute } from 'vue-router';
import { UploadFilled } from '@element-plus/icons-vue';
import { ElCascader, ElIcon, ElMessage, ElRadio, ElRadioGroup, ElUpload, genFileId } from 'element-plus';
import * as turf from '@turf/turf';
import JSZip from 'jszip';
import { cuttingToShp, getRelationById } from '@/apis/api-map-server';
import { load } from '@/common/common-loading';
import BorderBoxBg from '@/components/BorderBoxBg.vue';
import { UPLOAD_FILE_TYPE_ZIP } from '@/utils/helper';
import { LAYERS_GROUP_ID } from '@/utils/map-helper';
import {
  ADD_DRAW,
  ADD_LAYER_TO_MAP_BOX_MAP,
  AGENCY_MAP_SERVER,
  GET_MAPBOX_MAP,
  REMOVE_MAPBOX_LAYER,
  ZDFX_ANALYSES_RANGE,
} from '@/utils/map-utils';
import { High_Light_LAYER } from '@/utils/map-utils';
import { SPACE_QUERY_FUN } from '@/utils/map-utils';
import { REMOVE_DRAW } from '@/utils/map-utils';
import MapCoverResultPolygon from './MapCoverResultPolygon.vue';

const cascaderProps = {
  emitPath: false,
};

const emit = defineEmits(['coverMapClose', 'handleQueryInfo']);

const layerList = computed(() => {
  return mapImgList.value.map((item) => item?.children || []).flat(1);
});

const route = useRoute();
const mapImgList = ref([]);
const checked_layer = ref('1');
const modeRadio = ref(1);
const layerValue = ref('');
const fileList = ref([]);
const upload = ref(null);
const resultFeaturesShow = ref(false);
const resultFeatures = ref({});
const coverAnalysis = ref(null);
const rangeBox = ref([]);

// 关闭弹窗 并清理数据
const handleClose = () => {
  handleBtnQuery(2);

  emit('coverMapClose');
};

const getRelationByIdApi = async () => {
  const [err, data] = await getRelationById({
    menuCode: route.query?.code,
  });

  if (!err) {
    mapImgList.value = data.map((item) => {
      return {
        ...item,
        label: item.serviceName,
        value: item.serviceName,
        children:
          item?.children?.map((el) => {
            let id = `${item.id}${Math.random()}`;

            return {
              ...el,
              fid: item.id,
              id,
              label: el.layerMeta.name,
              value: id,
              url: AGENCY_MAP_SERVER(item, el),
            };
          }) || [],
      };
    });
  }
};

//图层选择
const handleChange = (e) => {
  let target = layerList.value.find((el) => el.id == e);

  if (target) {
    checked_layer.value = target;
    resultFeatures.value = {};
    resultFeaturesShow.value = false;
    fileList.value = [];
    rangeBox.value = [];
    REMOVE_MAPBOX_LAYER(LAYERS_GROUP_ID.TD_MAP_LAYER);
    REMOVE_MAPBOX_LAYER(`${LAYERS_GROUP_ID.High_Light_RESULT_LAYER}`);
    nextTick(() => {
      ADD_LAYER_TO_MAP_BOX_MAP(LAYERS_GROUP_ID.TD_MAP_LAYER, target);
    });
  }
};

// 分析方式选择
const onChangeRadio = () => {
  const map = GET_MAPBOX_MAP();

  if (map) {
    map.getCanvas().style.cursor = 'pointer';
  }

  REMOVE_DRAW();
  handleCloseQueryLayer();
  fileList.value = [];
  rangeBox.value = [];
  REMOVE_MAPBOX_LAYER(`${LAYERS_GROUP_ID.High_Light_RESULT_LAYER}`);
};

const handleMapAttributeQuery = () => {
  if (checked_layer.value == '1') {
    ElMessage.warning('请选择分析图层');

    return;
  }

  const map = GET_MAPBOX_MAP();

  fileList.value = [];
  rangeBox.value = [];
  REMOVE_MAPBOX_LAYER(`${LAYERS_GROUP_ID.High_Light_RESULT_LAYER}`);

  ADD_DRAW({ defaultMode: 'draw_polygon' });

  map.on('draw.create', handlePolygonQueryAnalysis);
};

// 文件手动上传
const handleUploadChange = (uploadFile) => {
  if (!UPLOAD_FILE_TYPE_ZIP(uploadFile.raw)) return ElMessage.warning('请上传zip文件');
  fileList.value = [uploadFile.raw];
};

const handleExceed = (files) => {
  upload.value.clearFiles();

  const file = files[0];

  file.uid = genFileId();
  upload.value.handleStart(file);
};

const handleBtnQuery = async (type) => {
  if (type == 2) {
    const map = GET_MAPBOX_MAP();

    if (map) {
      map.getCanvas().style.cursor = 'pointer';
      map.off('draw.create', handlePolygonQueryAnalysis);
    }

    REMOVE_DRAW();
    checked_layer.value = '1';
    modeRadio.value = 1;
    layerValue.value = '';
    fileList.value = [];
    rangeBox.value = [];
    handleCloseQueryLayer();
    REMOVE_MAPBOX_LAYER(LAYERS_GROUP_ID.TD_MAP_LAYER);
    REMOVE_MAPBOX_LAYER(`${LAYERS_GROUP_ID.High_Light_RESULT_LAYER}`);
  } else {
    if (checked_layer.value == '1') {
      ElMessage.warning('请选择分析图层');

      return;
    }

    if (modeRadio.value == 1) {
      if (!fileList.value.length) {
        ElMessage.warning('请上传数据');

        return;
      }

      handleDataUploadAnalysis();
    } else {
      // 框选分析
      if (!rangeBox.value.length) {
        ElMessage.warning('请框选分析的范围');

        return;
      }

      let mapParams = {
        id: checked_layer.value.fid,
        TYPENAME: checked_layer.value.label.replace('.shp', ''),
        coordinates: rangeBox.value[0].geometry.coordinates,
      };

      load.show('正在分析信息，请稍等...');
      REMOVE_MAPBOX_LAYER(`${LAYERS_GROUP_ID.High_Light_RESULT_LAYER}`);

      const queryInfo = await ZDFX_ANALYSES_RANGE(mapParams);

      if (queryInfo.features.length) {
        ElMessage({
          message: '查询成功',
          duration: 1000,
          type: 'success',
        });
        High_Light_LAYER(LAYERS_GROUP_ID.High_Light_RESULT_LAYER, queryInfo);
        resultFeatures.value = queryInfo;
        resultFeaturesShow.value = true;
      } else {
        ElMessage({
          message: '未分析出任何要素',
          duration: 1000,
          type: 'info',
        });

        handleCloseQueryLayer();
      }

      load.hide();
    }
  }
};

// 框选范围
const handlePolygonQueryAnalysis = (e) => {
  rangeBox.value = e.features;
};

// 数据上传分析
const handleDataUploadAnalysis = async () => {
  load.show('正在分析信息，请稍等...');

  const [err, data] = await cuttingToShp({
    shp: fileList.value[0],
    serviceId: checked_layer.value.fid,
    layerName: checked_layer.value.label,
  });

  if (!err) {
    coverAnalysis.value = data;
    fileChange(data.data);
  } else {
    load.hide();
    ElMessage.error('图层切割失败');
  }

  load.hide();
};

//解析文件
const fileChange = (param) => {
  const fileData = param;

  const zip = new JSZip();

  zip.loadAsync(fileData).then((res) => {
    const fileList = Object.keys(res.files);
    const pattern = new RegExp(/\S\.shp$/);
    const shpFile = fileList.find((i) => pattern.test(i));
    let geojsonArr = [];

    // console.log(shpFile, 'shpFile');

    zip
      .file(shpFile)
      .async('arraybuffer')
      .then(function (content) {
        // 这个就是文件中的内容
        window.shapefile
          .open(content)
          .then((source) => {
            source.read().then(function log(result) {
              if (result.done) {
                //解析完成

                var collection = turf.featureCollection(geojsonArr);

                var bbox = turf.bbox(collection);
                var bboxPolygon = turf.bboxPolygon(bbox);

                REMOVE_MAPBOX_LAYER(`${LAYERS_GROUP_ID.High_Light_RESULT_LAYER}`);
                resultFeatures.value = {};
                resultFeaturesShow.value = false;

                if (collection.features.length) {
                  High_Light_LAYER(LAYERS_GROUP_ID.High_Light_RESULT_LAYER, collection);
                  getMapAttributeQuery(bboxPolygon?.geometry?.coordinates);
                } else {
                  ElMessage.warning('未分析出结果');
                }

                return;
              }

              const json = result.value;

              geojsonArr.push(json);

              return source.read().then(log);
            });
          })
          .catch((error) => {
            console.error(error.stack);
            ElMessage.error('读取shp文件失败');
            load.hide();
          });
      });
  });
};

// 属性信息
const getMapAttributeQuery = async (coordinates) => {
  let mapParams = {
    id: checked_layer.value.fid,
    TYPENAME: checked_layer.value.label.replace('.shp', ''),
    coordinates: coordinates,
  };
  const queryInfo = await SPACE_QUERY_FUN(mapParams);

  if (queryInfo.features.length) {
    ElMessage({
      message: '查询成功',
      duration: 1000,
      type: 'success',
    });
    resultFeatures.value = queryInfo;
    resultFeaturesShow.value = true;
  }

  load.hide();
};

const handleCloseQueryLayer = () => {
  resultFeaturesShow.value = false;
  resultFeatures.value = {};
};

onMounted(() => {
  getRelationByIdApi();
});

onBeforeUnmount(() => {
  handleClose();
});
</script>
<template>
  <BorderBoxBg title="占地分析" class="analysis" @close="handleClose">
    <div class="item">
      <p>选择分析图层</p>
      <ElCascader
        v-model="layerValue"
        popper-class="cutting-pop bg-blue-400"
        class="pops"
        placeholder="选择图层"
        :options="mapImgList"
        :props="cascaderProps"
        @change="handleChange"
      />
      <p>选择分析方式</p>
      <ElRadioGroup v-model="modeRadio" @change="() => onChangeRadio()">
        <ElRadio :value="1">上传数据</ElRadio>
        <ElRadio :value="2">绘制范围</ElRadio>
      </ElRadioGroup>

      <div v-if="modeRadio == 1" class="mt-20px">
        <div class="item">
          <ElUpload
            ref="upload"
            :file-list="fileList"
            accept=".zip"
            :on-change="handleUploadChange"
            :auto-upload="false"
            :on-exceed="handleExceed"
            :limit="1"
            @remove="() => (fileList = [])"
          >
            <div>
              <ElIcon class="el-icon--upload" size="40">
                <UploadFilled />
              </ElIcon>
              <div>点击上传文件</div>
            </div>
            <template #tip>
              <div class="el-upload__tip">请将完整shp文件打包成zip格式上传</div>
            </template>
          </ElUpload>
        </div>
      </div>
      <div v-if="modeRadio == 2" class="mt-20px">
        <div class="polygon" @click="handleMapAttributeQuery('spatial_polygon')">空间（框选）</div>
      </div>

      <div class="btn_div">
        <div class="btn_select" @click="handleBtnQuery(1)">
          <p>分析</p>
        </div>
        <div class="btn_select" @click="handleBtnQuery(2)">
          <p>重置</p>
        </div>
      </div>
    </div>

    <MapCoverResultPolygon
      :polygon-show="resultFeaturesShow"
      :result-features="resultFeatures"
      :cover-analysis="coverAnalysis"
      @close-query-result-show="handleCloseQueryLayer"
    />
  </BorderBoxBg>
</template>

<style scoped lang="scss">
.analysis {
  top: 50%;
  bottom: auto;
  .item {
    text-align: center;

    :deep(.el-upload-list) {
      .el-upload-list__item-name,
      .el-icon {
        color: #fff;
      }

      .el-upload-list__item-name:hover,
      .el-icon:hover {
        color: #000;
      }
    }
  }

  .el-upload__tip {
    color: #eee;
  }
  .polygon {
    height: 40px;
    margin: 0 10px;
    line-height: 40px;
    text-align: center;
    background-color: #0dc4c49d;
    border-radius: 5px;
    cursor: pointer;
    &:hover {
      background-color: #0dc4c4e0;
    }
  }
  .btn_div {
    display: flex;
    justify-content: space-between;
    width: 100%;
    padding: 0 5px;
    text-align: center;
    .btn_select {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 110px;
      height: 42px;
      margin-top: 21px;
      margin-bottom: 17px;
      font-size: 16px;
      font-family: Source Han Sans CN, Source Han Sans CN-Medium;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      p {
        margin: 0;
      }
      &:hover {
        background-color: #e6f5fe;
      }
      &:first-child {
        color: #33c7d4;
        background: rgba(25, 131, 145, 0.3);
      }
      &:nth-child(2) {
        color: #999999;
        background: rgba(153, 153, 153, 0.3);
      }
    }
  }

  :deep(.el-radio) {
    color: #e8e8e8;
  }

  :deep(.el-radio__input.is-checked + .el-radio__label) {
    color: #33c7d4;
  }
}
</style>
